/**
 * @file order_manager.cpp
 * @brief 订单管理器的实现
 * 
 * @details 该文件实现了订单管理器（OrderManager）类的方法，
 * 包括创建新订单和取消现有订单的功能。
 * 这些方法与交易引擎交互，发送客户端请求并管理订单状态。
 * 
 * @author 原作者
 * @date 2023
 */

#include "order_manager.h"
#include "trade_engine.h"

namespace Trading {
  /**
   * @brief 发送具有指定属性的新订单，并更新传入的OMOrder对象
   * 
   * @details 创建并发送一个新的订单到交易所，并使用指定的属性更新传入的OMOrder对象。
   * 该方法执行以下操作：
   * 1. 创建一个新的客户端请求，包含证券标识符、订单ID、侧向、价格和数量
   * 2. 通过交易引擎发送该请求
   * 3. 使用指定的属性更新OMOrder对象，并将状态设置为 PENDING_NEW
   * 4. 增加下一个可用的订单ID
   * 5. 记录日志
   * 
   * @param order 要更新的OMOrder对象指针
   * @param ticker_id 证券标识符
   * @param price 订单价格
   * @param side 订单侧向（买入或卖出）
   * @param qty 订单数量
   * @return void
   */
  auto OrderManager::newOrder(OMOrder *order, TickerId ticker_id, Price price, Side side, Qty qty) noexcept -> void {
    const Exchange::MEClientRequest new_request{Exchange::ClientRequestType::NEW, trade_engine_->clientId(), ticker_id,
                                                next_order_id_, side, price, qty};
    trade_engine_->sendClientRequest(&new_request);

    *order = {ticker_id, next_order_id_, side, price, qty, OMOrderState::PENDING_NEW};
    ++next_order_id_;

    logger_->log("%:% %() % Sent new order % for %\n", __FILE__, __LINE__, __FUNCTION__,
                 Common::getCurrentTimeStr(&time_str_),
                 new_request.toString().c_str(), order->toString().c_str());
  }

  /**
   * @brief 发送取消指定订单的请求，并更新传入的OMOrder对象
   * 
   * @details 为指定的订单创建并发送一个取消请求到交易所，并将订单状态更新为 PENDING_CANCEL。
   * 该方法执行以下操作：
   * 1. 创建一个取消请求，包含订单的原始信息（证券标识符、订单ID、侧向、价格和数量）
   * 2. 通过交易引擎发送该请求
   * 3. 将订单状态更新为 PENDING_CANCEL
   * 4. 记录日志
   * 
   * 该方法不会立即取消订单，而是发送一个取消请求并等待交易所的确认。
   * 
   * @param order 要取消的OMOrder对象指针
   * @return void
   */
  auto OrderManager::cancelOrder(OMOrder *order) noexcept -> void {
    const Exchange::MEClientRequest cancel_request{Exchange::ClientRequestType::CANCEL, trade_engine_->clientId(),
                                                   order->ticker_id_, order->order_id_, order->side_, order->price_,
                                                   order->qty_};
    trade_engine_->sendClientRequest(&cancel_request);

    order->order_state_ = OMOrderState::PENDING_CANCEL;

    logger_->log("%:% %() % Sent cancel % for %\n", __FILE__, __LINE__, __FUNCTION__,
                 Common::getCurrentTimeStr(&time_str_),
                 cancel_request.toString().c_str(), order->toString().c_str());
  }
}
